"""
@release: fsray-api-alpha
@file: machine.py
@author: lingdubing
@desc: 操作电动车行为的接口层
@character: utf-8
"""

from fastapi import  APIRouter,Depends
from schemas.response import *
from service.MachineService import MachineService
from service.AreaService import AreaService
from service.RecordService import RecordService
from service.UserService import UserService
from schemas.machine_schemas import *
from config import settings
from core.Auth import check_permission
from core.Utils import is_machine_in_area,get_route_coordinates
import ast
from core.Task import simulate_ev_ride


router = APIRouter()

@router.post("/machine_list", summary="查询电动车列表", response_model=ReturnDataModel,
            dependencies=[Depends(check_permission)])
async def get_machine_list(query: MachinePaingtionModel):
    """
    获取电动车列表
    :param query:
    :return:
    """
    machine_service = MachineService()

    machine_list, total = machine_service.get_machine_list(page=query.page, page_size=query.page_size,
                                                           status=query.status, area_id=query.area_id,
                                                           machine_id=query.machine_id)

    area_service = AreaService()

    final_list = []

    for val in machine_list:
        area_info = area_service.get_area_by_id(val.area_id)
        machine_info = {
            "create_time": val.create_time,
            "update_time": val.update_time,
            "machine_id": val.machine_id,
            "machine_point": [val.machine_point["longitude"], val.machine_point["latitude"]],
            "machine_battery": val.machine_battery,
            "area_name": area_info.area_name,
            "status": val.status,
            "machine_photo": val.machine_photo
        }
        final_list.append(machine_info)

    machine_service.close()
    area_service.close()

    return ReturnDataModel(data=final_list, total=total, success=True, code=STATUS_CODE["success"], message="查询成功")

@router.post("/machine_add", summary="添加电动车", response_model=ReturnNoneDataModel, dependencies=[Depends(check_permission)])
async def add_machine(machine: AddMachineModel, user_info: tuple = Depends(check_permission)):
    """
    添加电动车
    :param machine:
    :return:
    """

    machine_service = MachineService()
    area_service = AreaService()
    user_id, role_id = user_info

    area_info = area_service.get_all_area()
    area_info_list = []
    for val in area_info:
        area_info = {
            "area_id": val.area_id,
            "area_desc": ast.literal_eval(val.area_desc)
        }
        area_info_list.append(area_info)



    # 判断电动车是否在区域内
    area_id = is_machine_in_area(machine.machine_point, area_info_list)
    if area_id != 0:
        machine_service.create_machine(machine_point=machine.machine_point, area_id=area_id, user_id=user_id)
        return ReturnNoneDataModel(success=True, code=STATUS_CODE["success"], message="添加成功")
    else:
        return ReturnNoneDataModel(success=False, code=STATUS_CODE["error"], message="电动车不在区域内")

@router.get("/machine_delete", summary="删除电动车", response_model=ReturnNoneDataModel, dependencies=[Depends(check_permission)])
async def delete_machine(machine_id: str):
    """
    删除电动车
    :param machine_id:
    :return:
    """

    machine_service = MachineService()
    record_service = RecordService()

    machine_info = machine_service.get_machine_by_id(machine_id)

    if machine_info is None:
        return ReturnNoneDataModel(success=False, code=STATUS_CODE["error"], message="该电动车不存在")
    else:
        record_list = record_service.get_all_by_machine_id(machine_id)
        if record_list is not None:
            for val in record_list:
                record_service.delete(val)
        machine_service.delete(machine_info)
        return ReturnNoneDataModel(success=True, code=STATUS_CODE["success"], message="删除成功")


@router.post("/start_ride", summary="开始骑行", dependencies=[Depends(check_permission)])
async def start_ride(ride: RideMachineModel, user_info: tuple = Depends(check_permission)):
    """
    开始骑行
    :return:
    """
    user_id = user_info[0]
    # 先检查电量和状态是否为可骑行
    machine_service = MachineService()
    user_service = UserService()
    machine_info = machine_service.get_machine_by_id(ride.machine_id)
    user_info = user_service.get_user_by_id(user_id)

    if user_info is None or user_info.user_status != 1:
        machine_service.close()
        user_service.close()
        return ReturnNoneDataModel(code=STATUS_CODE["warning"], message="用户不在可骑行状态", success=False)
    if machine_info.machine_battery < 20:
        machine_service.close()
        user_service.close()
        return ReturnNoneDataModel(code=STATUS_CODE["warning"], message="电动车电量不足,请换乘骑行", success=False)
    if machine_info.status != 1:
        machine_service.close()
        user_service.close()
        return ReturnNoneDataModel(code=STATUS_CODE["warning"], message="电动车不在可骑行状态,请换乘骑行",
                                       success=False)
    else:
        # 更新状态为骑行中
        machine_info.status = 0
        machine_service.create(machine_info)
        # 更新用户状态为骑行中
        user_info.user_status = 2
        user_service.create(user_info)

        # 计算路线等，调用Celery任务
        route = get_route_coordinates(ride.machine_origin, ride.machine_destination)
        task = simulate_ev_ride.apply_async(args=[ride.machine_id, user_id, route])
        machine_service.close()
        user_service.close()
        return ReturnNoneDataModel(code=STATUS_CODE["success"], message=f"开始骑行,任务id为{task.id}", success=True)















